#include "linevalidator.h"
#include <QDebug>
/**Used for checking which line is a valid log command and what line is just rubbish. */

LineValidator::LineValidator()
{
    // TODO these should not be hardcoded... "^LOG:  duration: \\d+\\.\\d+ ms  statement: "
    this->setDurationExtractionPattern( "^LOG:  duration: (\\d+\\.\\d*) ms  statement: ");
    //this->setDurationExtractionPattern( "^LOG:  duration: (\\d+\\.\\d*)");
    this->setStatementExtractionPattern("^LOG:  duration: \\d+\\.\\d* ms  statement: (.+)");
}

void LineValidator::setValidLinePattern(QString regexp)
{
    this->m_validLinePattern = QRegExp(regexp);
    this->m_validString = regexp;
}

void LineValidator::setInValidLinePattern(QString regexp)
{
    this->m_inValidLinePattern = QRegExp(regexp);
    this->m_inValidString = regexp;
}

bool LineValidator::isInValidLogLine(QString& line)
{
    //if (line.startsWith("NOTICE:") || line.startsWith("ERROR:") || line.startsWith("STATEMENT:"))
    if (line.indexOf(m_inValidLinePattern) >= 0 || ! this->isValidLogLine(line) )
        return true;
    else
        return false;
}

bool LineValidator::isValidLogLine(QString& line)
{
    //if (line.startsWith("NOTICE:") || line.startsWith("ERROR:") || line.startsWith("STATEMENT:"))
    if (line.indexOf(m_validLinePattern) >= 0)
        return true;
    else
        return false;
}

void LineValidator::setDurationExtractionPattern(QString regexp)
{
    this->m_durationString=regexp;
    this->m_durationPattern = QRegExp(regexp);
}

void LineValidator::setStatementExtractionPattern(QString regexp)
{
    this->m_statementString = regexp;
    this->m_statementPattern = QRegExp(regexp);
}

bool LineValidator::extractDurationAndStatement(QString& line,qreal& duration,QString& statement)
{
    this->m_durationPattern.indexIn(line,0);
    QString tmp = this->m_durationPattern.cap(1);
    bool ok;
    duration = tmp.toDouble(&ok);
//qDebug()<<"duration="<<duration<<" index in gives "<<this->m_durationPattern.indexIn(line,0)<<" for line = "<<line;
    if (!ok)
    {
        qDebug()<<"could not extract duration from "<<line<<" got value "<<tmp;
        return false;
    }
    //else
    //    qDebug()<<"SUCCESS: cap="<<tmp;

    this->m_statementPattern.indexIn(line,0);
    statement = this->m_statementPattern.cap(1);
    return statement.length()>0; // this is resonable to assume since we have a valid line.
}

void LineValidator::annonymizeStatement(QString& statement)
{
    QString start=statement;

    statement.replace(QRegExp("'\\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d:\\d\\d'"),"TIMESTAMP"); // 'timestamp'
    statement.replace(QRegExp("'\\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d:\\d\\d:\\d\\d\\.\\d+'"),"TIMESTAMP"); // 'timestamp' with milli/microseconds

    QRegExp tirx("'\\d+ (MINUTES|SECONDS|HOURS|DAYS)'");
    tirx.setCaseSensitivity(Qt::CaseInsensitive);
    statement.replace(tirx,"TIMEINTERVAL"); // time intervals


    statement.replace(QRegExp("''('')+"),"''"); // keep at most two pairs of ' (i.e. four consecutive ' characters). All else is just headake
    /* At the first ' check what the next character is. If it is
       end of line = syntax error, should not happen
       '' we have a string that begins with '' (we can not have single ' in a string (syntax error)
       ' and a non-' character. Then we have an empty string
       non-' character Then we have the beginning of a string. The string is terminated at the first ' character. After that we continue to search for new '

       After we have done this, we have eliminated all double ' characters ('') in the beginning or the end of strings so we have at most two consecutive '
        characters. This leads to a simpler case att the first '. Either the next character is a ' and we have an empty string, or the next character is
        the end of the line (and then we have an error) or we have the beginning of a string. Then just parse to the next '. If that ' character is followed
        by another ' just keep on (ignore the fact that this is the case of having '' within a string. We fix that now.

    */
    QRegExp strrx("'[^'].*'");
    strrx.setMinimal(true); // not greedy
    QString oldstatement;
    do
    {
        oldstatement= statement;
        statement.replace(strrx,"STRING");
    } while (oldstatement !=statement);
    statement.replace(QRegExp("STRING(STRING)+"),"STRING"); // a string 'fo''o' results in STRINGSTRING
    statement.replace(QRegExp("''"),"EMPTYSTRING");
    statement.replace(QRegExp("=\\d+[.]\\d+"),"=DOUBLE"); // = double
    statement.replace(QRegExp("<\\d+[.]\\d+"),"<DOUBLE"); // = double
    statement.replace(QRegExp(">\\d+[.]\\d+"),">DOUBLE"); // = double
    statement.replace(QRegExp("<=\\d+[.]\\d+"),"<=DOUBLE"); // = double
    statement.replace(QRegExp(">=\\d+[.]\\d+"),">=DOUBLE"); // = double
    statement.replace(QRegExp(",\\d+,"),",DOUBLE,"); // ,double,
    statement.replace(QRegExp(",\\d+ "),",DOUBLE "); // ,double (space after
    statement.replace(QRegExp(",\\d+$"),",DOUBLE "); // ,double end of line

    statement.replace(QRegExp("=\\d+"),"=INTEGER"); // =integer
    statement.replace(QRegExp(">\\d+"),">INTEGER"); // =integer
    statement.replace(QRegExp("<\\d+"),"<INTEGER"); // =integer
    statement.replace(QRegExp(">=\\d+"),">=INTEGER"); // =integer
    statement.replace(QRegExp("<=\\d+"),"<=INTEGER"); // =integer

    statement.replace(QRegExp(",\\d+,"),",INTEGER,"); // ,integer,
    statement.replace(QRegExp(",\\d+ "),",INTEGER "); // ,integer (space after
    statement.replace(QRegExp(",\\d+$"),",INTEGER "); // ,integer end of line
    //qDebug()<<"REPLACE DONE: "<<start<<" became "<<statement;
    //qSort(list.begin(), list.end(), qGreater<int>());
}



